static double gsum = 0, hsum = 0, ssum = 0, usum = 0;
#ifdef __sw_host__
__attribute__((sw_64_host)) double add(double a, double b){
  hsum += a*b;
  gsum += a*b;
  return a * b;
}
#endif

#ifdef __sw_slave__
__attribute__((sw_64_slave)) double add(double a, double b){
  ssum += a*b;
  gsum += a*b;
  return a * b;
}
#endif
double default_accumulate(double sum){
  gsum *= sum;
}
double default_add(double a, double b){
  default_accumulate(a+b);
}
__attribute__((noinline)) __attribute__((sw_64_host))  __attribute__((sw_64_slave)) void hadd(double a, double b){
  gsum += a*b;
}

__attribute__((sw_64_host))  __attribute__((sw_64_slave)) void hadd_caller(double a, double b){
  default_add(a, b);
  hadd(a, b);
}
__attribute__((target("host"))) int main(int argc, char **argv){
  add(argc, argc);
  return (long)hsum + (long)__builtin_slave_func((void*)(double(*)(double, double))add);
}
